ggvote_plot <- function(pred,
                        add_descriptives_from_model = NULL,
                        scale_factor_descriptives = NULL,
                        x1,
                        x2, 
                        x3,
                        ylim = rep(NA_real_, 2L),
                        ytitle = "Prediction",
                        font_size = 15L) {
  if (not(is.null(add_descriptives_from_model))) {
    sum_data <- mod$model %>%
      mutate(n = n()) %>%
      group_by(!!as.name(x2),!!as.name(x1),!!as.name(x3)) %>%
      summarize(sample_prop = n() / unique(n))
    
    pred <- pred %>%
      left_join(sum_data, by = c(x2, x1, x3))
    
    if (not(is.null(scale_factor_descriptives))) {
      pred <- pred %>%
        mutate(sample_prop = (sample_prop / max(sample_prop)) * 
                 (scale_factor_descriptives * 
                    max(c(upper, ylim[2]), na.rm = TRUE)))
    }
  }
  
  ## Expected values
  vote_plot <- pred %>%
    ggplot(
      aes(x = !!as.name(x1),
          y = Prediction)
    ) +
    geom_point(position = position_dodge(width = 1)) +
    geom_errorbar(
      aes(ymin = lower,
          ymax = upper),
      position = position_dodge(width = 1),
      width = 0
    ) +
    geom_hline(yintercept = 0) +
    facet_grid(. ~ get(eval(x3)) ~ get(eval(x2))) +
    theme(
      panel.spacing = unit(0.75, "lines")
    )  +
    theme(text = element_text(size = font_size)) +
    ylim(ylim) + 
    ylab(ytitle)
  
  ## Descriptives
  if (not(is.null(add_descriptives_from_model))) {
    vote_plot <- vote_plot +
      geom_bar(
        data = pred,
        aes(x = !!as.name(x1),
            y = sample_prop),
        stat = "identity",
        alpha = 0.2
      )
  }
  
  ## Return
  return(vote_plot)
}